import {
  makeGlobalGroupImports,
  makeUseClient,
  wrapGlobalProviderWithCustomValue,
} from "@/wab/shared/codegen/react-p/serialize-utils";
import { exportActiveSplitsConfig } from "@/wab/shared/codegen/splits";
import { ExportOpts } from "@/wab/shared/codegen/types";
import { SplitStatus } from "@/wab/shared/core/splits";
import {
  Site,
  isKnownGlobalVariantSplitContent,
} from "@/wab/shared/model/classes";

export function makeSplitsProviderBundle(
  site: Site,
  projectId: string,
  opts: Partial<ExportOpts>
) {
  if (site.splits.length === 0) {
    return undefined;
  }

  const runningSplits = site.splits.filter(
    (s) => s.status === SplitStatus.Running
  );

  const referencedGlobalVariantGroups = site.globalVariantGroups.filter(
    (vg) => {
      return runningSplits.some((s) => {
        return s.slices.some((slice) => {
          return slice.contents.some((content) => {
            if (isKnownGlobalVariantSplitContent(content)) {
              return content.group === vg;
            }
            return false;
          });
        });
      });
    }
  );

  let content = `{children}`;

  for (const globalVariantGroup of referencedGlobalVariantGroups) {
    content = wrapGlobalProviderWithCustomValue(
      globalVariantGroup,
      content,
      false,
      `getGlobalContextValueFromVariation("${globalVariantGroup.uuid}", variation)`
    );
  }

  // This should be a codegen exclusive module that shouldn't be included in loader bundle

  const module = `
    /* eslint-disable */
    /* tslint:disable */
    // @ts-nocheck
    // This class is auto-generated by Plasmic; please do not edit!
    // Plasmic Project: ${projectId}
    ${makeUseClient(opts)}
    import * as React from "react";
    import { getActiveVariation } from "@plasmicapp/react-web/lib/splits";
    ${makeGlobalGroupImports(referencedGlobalVariantGroups)}

    type GetActiveVariationParams = Partial<
      Parameters<typeof getActiveVariation>[0]
    >;

    export interface PlasmicSplitsProviderProps extends GetActiveVariationParams {
      children?: React.ReactNode;
    };

    export const splits = ${JSON.stringify(
      exportActiveSplitsConfig(site, projectId)
    )};

    export function getGlobalContextValueFromVariation(groupId: string, variation: Record<string, string>) {
      let groupValue: string | undefined = undefined;
      Object.keys(variation).forEach((variationKey: string) => {
        const [_type, splitId] = variationKey.split(".");
        const sliceId = variation[variationKey];
        const split = splits.find(
          (s) => s.id === splitId || s.externalId === splitId
        );
        if (split) {
          const slice = split.slices.find(
            (s) => s.id === sliceId || s.externalId === sliceId
          );
          if (slice) {
            const content = slice.contents.find(
              (c) => c.groupId === groupId
            );
            if (content) {
              groupValue = content.variant;
            }
          }
        }
      });
      return groupValue;
    };

    export default function PlasmicSplitsProvider(props: PlasmicSplitsProviderProps) {
      const { children, traits, ...rest } = props;
      const variation = getActiveVariation({
        splits,
        traits: traits ?? {},
        ...rest,
      });

      return (
        <>
          ${content}
        </>
      );
    };
  `;

  return {
    id: projectId,
    module,
  };
}
